/*
 * =====================================================================================
 *
 *       Filename:  
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  06/04/14 10:01:41
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Andy (gk), andy_y_li@163.com
 *        Company:  RD
 *
 * =====================================================================================
 */



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h> 
#include <errno.h>
#include "utility.h"
#include "argvs.h"

#define BUFSIZE 128
#define is_delim(x) ((x)==' '|| (x)=='\t')

char *Get_cmd(char *prompt,FILE *fp)
{
    char *buf = NULL;
    int bufspace = 0;
    int pos = 0;
    int c;

    printf("%s",prompt);
    while ((c = getc(fp)) != EOF) {
        if (pos + 1 >= bufspace) {
            if (bufspace == 0) {
                buf = malloc(BUFSIZE);
            }
            else {
                char *temp = realloc(buf,bufspace+BUFSIZE);
                if (temp == NULL) {
                    opps("memory error:",NULL);
                }
                buf = temp;
                bufspace += BUFSIZE;
            }
        }

        // end of command?
        if (c == '\n') {
            break;
        }
        // no,add to buffer
        buf[pos++] = c;
    }

    if ((c == EOF) && (pos == 0)) {
        printf("memory error!");
        return NULL;
    }

    buf[pos] = '\0';
    return buf;

}

char *newstr(char *s,int len)
{
    char *rv = malloc(len + 1);
    assert(rv != NULL);

    rv[len] = '\0';
    strncpy(rv,s,len);
    return rv;
}

char **splitline(char *line)
{
    char **args;
    int spots = 0;
    int bufspace = 0;
    int argnum = 0;
    char *cp = line;
    char *start = NULL;
    int len;

    if (line == NULL) {
        printf("Parameter error!\n");
        return NULL;
    }

    args = malloc(BUFSIZE);
    bufspace = BUFSIZE;
    spots = BUFSIZE/sizeof(char *);

    while (*cp != '\0') {
        while (is_delim(*cp)) {
            cp++;
        }
        if (*cp == '\0') {
            break;
        }

        if (argnum + 1 >= spots) {
            char **temp = realloc(args,bufspace+BUFSIZE);
            if (temp == NULL){
                opps("memory error:",NULL);
            }
            args = temp;
            bufspace += BUFSIZE;
            spots += BUFSIZE/sizeof(char *);
        }
        
        start = cp;
        len = 1;
        while (*++cp != '\0' && !(is_delim(*cp))) {
            len++;
        }
        args[argnum++] = newstr(start,len);
    }
    args[argnum] = NULL;
        
    return args;
}

void freelist(char **list)
{
    char **cp = list;
    while (*cp) {
        free(*cp++);
    }
    free(list);

}

static int get_input(char *buf)
{
	int len = 0;
	int ch;

	ch = getchar();
	while(len < CMD_SIZE - 1 && ch != '\n'){
		buf[len++] = ch;
		ch = getchar();
	}
	
	if (len == CMD_SIZE - 1){
		printf("command is too long\n");
	}

	buf[len] = '\0';

	return len;
}

int makeargv(const char *s,const char *delimiters,char ***argvp)
{
	int error;
	int i;
	int numtokens;
	const char *snew;
	char *t;

	if ((s == NULL) || (delimiters == NULL) || (argvp == NULL)){
		errno = EINVAL;
		return -1;
	}

	*argvp = NULL;
	snew = (char *)(s + strspn(s,delimiters));
	if ((t = (char *)malloc(strlen(snew) + 1)) == NULL){
		return -1;
	}
	strcpy(t,snew);

	numtokens = 0;
	if (strtok(t,delimiters) != NULL){
		for(numtokens = 1;strtok(NULL,delimiters) != NULL;numtokens++);
	}
	else{
		free(t);
		return -1;
	}
	if ((*argvp = (char **)malloc((numtokens + 1) * sizeof(char *))) == NULL){
		error = errno;
		free(t);
		errno = error;
		return -1;
	}
	
	if (numtokens == 0){
		free(t);
	}
	else{
		strcpy(t,snew);
		**argvp = strtok(t,delimiters);
		for(i = 1;i < numtokens;i++){
			(*argvp)[i] = strtok(NULL,delimiters);
		}
	}
	(*argvp)[numtokens] = NULL;

	return numtokens;
}

void freemakeargv(char **argv)
{
	if (argv == NULL)
		return;
	if (*argv != NULL)
		free(*argv);
	free(argv);
}

int get_cmd(char ***argv)
{
	char buf[CMD_SIZE];
	int argc = 0;

	int len = get_input(buf);

	if (len){
		argc = makeargv(buf," ",argv);
		if (argc == -1){
			perror("makeargv");
			return -1;
		}
	}
	return argc;
}

